package com.fsl.springcloudstream.consumer;

import com.fsl.springcloudstream.messaging.SinkClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessagingException;
import org.springframework.messaging.SubscribableChannel;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * @author dell
 * 消息消费的三种方式
 * 这个类里面定义了三种对消息的监听方式，并且这三种方式是互斥的，也就是同一条消息只有一个方法去接收到,接收顺序如下：
 * @StreamListener----->@ServiceActivator--------->subscribe
 */
@Component
@EnableBinding(SinkClient.class)
public class StreamMessageConsumer {

    @Autowired
    @Qualifier(SinkClient.INPUT)
    private SubscribableChannel subscribableChannel;

    @Autowired
    private SinkClient sinkClient;

    /**
     * 方式一
     * 通过异步回调的方式来接收消息
     * 当字段全部注入完成之后执行的方法
     */
    @PostConstruct
    public void init(){
        //实现异步回调的方式来接收消息
        subscribableChannel.subscribe(new MessageHandler() {
            @Override
            public void handleMessage(Message<?> message) throws MessagingException {
                //假如监听到的信息是类似[B@7767082c这种的信息，那么可能是kafka或者rabbitmq的版本与当前springcloud stream的版本不一致导致的
                System.out.println("使用异步回调监听到的消息是--------------->" + message.getPayload());
            }
        });

        //也可以用下面的这种方式消费， sinkClient.input() = subscribableChannel
        //sinkClient.input().subscribe();
    }

    /**
     * 方式二
     * 通过ServiceActivator来实现消息的消费
     * @param message
     */
    @ServiceActivator(inputChannel = SinkClient.INPUT)
    public void onMessage(String message){
        System.out.println("使用@ServiceActivator监听到的消息是--------------->" + message);
    }

    /**
     * 方式三
     * 标准的springcloud stream的方式监听消息
     * @param message
     */
    @StreamListener(SinkClient.INPUT)
    public void process(String message){
        System.out.println("使用@StreamListener监听到的消息是------------->" + message);
    }


}
